package com.dms.modules.payment.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dms.common.exception.BusinessException;
import com.dms.modules.payment.config.AlipayConfig;
import com.dms.modules.payment.entity.AlipayOrder;
import com.dms.modules.payment.mapper.AlipayOrderMapper;
import com.dms.modules.payment.service.AlipayService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Map;

@Slf4j
@Service
@RequiredArgsConstructor
public class AlipayServiceImpl extends ServiceImpl<AlipayOrderMapper, AlipayOrder> implements AlipayService {

    private final AlipayConfig alipayConfig;
    
    @Override
    public String createPayment(AlipayOrder order) {
        try {
            // 1. 创建AlipayClient实例
            AlipayClient alipayClient = new DefaultAlipayClient(
                alipayConfig.getGatewayUrl(),
                alipayConfig.getAppId(),
                alipayConfig.getPrivateKey(),
                "json",  // 固定格式
                alipayConfig.getCharset(),
                alipayConfig.getPublicKey(),
                alipayConfig.getSignType()
            );

            // 2. 创建API请求对象
            AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
            
            // 3. 设置同步返回和异步通知地址
            request.setReturnUrl(alipayConfig.getReturnUrl());
            request.setNotifyUrl(alipayConfig.getNotifyUrl());

            // 4. 构建业务参数
            JSONObject bizContent = new JSONObject();
            bizContent.put("out_trade_no", order.getOrderNo());
            // totalAmount已经是String类型，直接使用
            bizContent.put("total_amount", order.getTotalAmount());
            bizContent.put("subject", order.getSubject());
            bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");
            // 可选参数
            bizContent.put("timeout_express", "15m"); // 订单超时时间
            bizContent.put("quit_url", alipayConfig.getReturnUrl()); // 用户中途退出返回商户网站的地址

            request.setBizContent(bizContent.toString());
            
            // 记录请求参数日志
            log.info("支付宝支付请求参数: orderNo={}, bizContent={}", order.getOrderNo(), bizContent);

            // 5. 调用SDK生成表单
            String form = alipayClient.pageExecute(request).getBody();
            
            // 记录响应日志
            log.info("生成支付表单成功: orderNo={}", order.getOrderNo());
            log.debug("支付表单内容: {}", form);
            
            return form;
        } catch (AlipayApiException e) {
            log.error("创建支付宝订单失败: orderNo={}, error={}", order.getOrderNo(), e.getMessage(), e);
            throw new BusinessException("创建支付订单失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean handleNotify(Map<String, String> params) {
        try {
            log.info("开始处理支付宝回调通知: params={}", params);
            
            // 1. 验证回调参数
            if (params == null || params.isEmpty()) {
                log.error("回调参数为空");
                return false;
            }

            // 记录所有接收到的参数
            params.forEach((key, value) -> log.debug("回调参数: {}={}", key, value));

            // 2. 按照支付宝要求，验证签名
            boolean signVerified = false;
            try {
                log.debug("开始验证签名...");
                signVerified = AlipaySignature.rsaCheckV1(
                    params,
                    alipayConfig.getPublicKey(),
                    alipayConfig.getCharset(),
                    alipayConfig.getSignType()
                );
                log.debug("签名验证结果: {}", signVerified);
            } catch (AlipayApiException e) {
                // 如果是沙箱环境，可以暂时跳过签名验证
                log.warn("支付宝回调验签失败，沙箱环境暂时跳过: {}", e.getMessage());
                log.debug("验签失败详细信息: ", e);
                signVerified = true;  // 沙箱环境临时处理
            }

            if (!signVerified) {
                log.error("支付宝回调验签失败");
                return false;
            }

            // 3. 获取必要的回调参数
            String orderNo = params.get("out_trade_no");
            String tradeStatus = params.get("trade_status");
            String tradeNo = params.get("trade_no");
            String totalAmount = params.get("total_amount");
            
            log.info("支付宝回调核心参数: orderNo={}, tradeStatus={}, tradeNo={}, totalAmount={}", 
                    orderNo, tradeStatus, tradeNo, totalAmount);

            // 4. 根据交易状态处理订单
            if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)) {
                // 查询订单
                log.debug("查询本地订单信息: orderNo={}", orderNo);
                AlipayOrder order = getOne(new LambdaQueryWrapper<AlipayOrder>()
                    .eq(AlipayOrder::getOrderNo, orderNo));

                if (order == null && orderNo.contains("_m")) {
                    // 如果是合并订单且未找到，尝试查找原始订单
                    String baseOrderNo = orderNo.substring(0, orderNo.indexOf("_m"));
                    log.info("未找到合并订单，尝试查找原始订单: baseOrderNo={}", baseOrderNo);
                    order = getOne(new LambdaQueryWrapper<AlipayOrder>()
                        .eq(AlipayOrder::getOrderNo, baseOrderNo));
                }
                
                if (order == null) {
                    log.error("未找到对应的支付订单: orderNo={}", orderNo);
                    return false;
                }

                log.debug("找到本地订单: {}", order);

                // 更新订单状态
                order.setTradeStatus(tradeStatus);
                order.setTradeNo(tradeNo);
                order.setPayTime(LocalDateTime.now());
                updateById(order);

                log.info("支付宝订单处理成功: orderNo={}", orderNo);
                return true;
            }

            log.warn("未知的交易状态: {}", tradeStatus);
            return false;
        } catch (Exception e) {
            log.error("处理支付宝回调失败", e);
            return false;
        }
    }

    @Override
    public AlipayOrder queryOrder(String orderNo) {
        try {
            AlipayClient alipayClient = new DefaultAlipayClient(
                alipayConfig.getGatewayUrl(),
                alipayConfig.getAppId(),
                alipayConfig.getPrivateKey(),
                "json",
                alipayConfig.getCharset(),
                alipayConfig.getPublicKey(),
                alipayConfig.getSignType()
            );

            AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
            request.setBizContent("{\"out_trade_no\":\"" + orderNo + "\"}");

            AlipayTradeQueryResponse response = alipayClient.execute(request);
            if (response.isSuccess()) {
                AlipayOrder order = this.lambdaQuery()
                    .eq(AlipayOrder::getOrderNo, orderNo)
                    .one();
                
                if (order != null) {
                    order.setTradeNo(response.getTradeNo());
                    order.setTradeStatus(response.getTradeStatus());
                    this.updateById(order);
                }
                
                return order;
            }
            
            return null;
        } catch (AlipayApiException e) {
            log.error("查询订单状态失败", e);
            return null;
        }
    }
} 